%读excel表格内容
filename1='F:\科研\大模型\拓扑图线路\运行方式1-branch_reordered.xlsx';
origin_lines_dataTable=readtable(filename1,'VariableNamingRule','preserve');


folderPath = 'F:\科研\大模型\拓扑图线路\输出'; % 指定文件夹路径
linenamexlsx = fullfile(folderPath, 'lines3.xlsx'); % 创建完整文件路径
includenamexlsx = fullfile(folderPath, 'include3.xlsx'); % 创建完整文件路径
breakernamexlsx = fullfile(folderPath, 'breaker.xlsx'); % 创建完整文件路径

%简化前线路
origin_lines=struct('EdgeNo',{},'F_Node',{},'F_Node_map',{},'T_Node',{},'T_Node_map',{},'r',{},'x',{},'b',{},'type',{},'typeid',{});
for i=1:size(origin_lines_dataTable,1)
    id=origin_lines_dataTable(i,1);
    F_Node=origin_lines_dataTable(i,2);
    F_Node_map=origin_lines_dataTable(i,3);
    T_Node=origin_lines_dataTable(i,4);
    T_Node_map=origin_lines_dataTable(i,5);
    r=origin_lines_dataTable(i,6);
    x=origin_lines_dataTable(i,7);
    b=origin_lines_dataTable(i,8);
    type=origin_lines_dataTable(i,12);
    typeid=origin_lines_dataTable(i,13);
    origin_lines(end+1)=struct('EdgeNo',id,'F_Node',F_Node,'F_Node_map',F_Node_map,'T_Node',T_Node,'T_Node_map',T_Node_map,'r',r,'x',x,'b',b,'type',type,'typeid',typeid);
end
%简化后线路
lines=struct('id',{},'from_bus',{},'from_bus_map',{},'to_bus',{},'to_bus_map',{},'resistance',{},'reactance',{},'susceptance',{},'is_active',{});
%简化前后对应关系
include=struct('lines',{},'origin_lines',{},'F_Node',{},'T_Node',{});


%构建父子节点关系
FT = containers.Map('KeyType','double','ValueType','any');
for i = 1:numel(origin_lines)
    a=origin_lines_dataTable(i,2);
    b=origin_lines_dataTable(i,4);
    a1=table2array(a);
    b1=table2array(b);
    % 添加a到b的连接
    if FT.isKey(a1)
        FT(a1) = [FT(a1),{b1}];
    else
        FT(a1) = {b1};
    end
    % 添加b到a的连接    
    if FT.isKey(b1)        
        FT(b1) = [FT(b1),{a1}];
    else
        FT(b1) = {a1};
    end
end
% keys = FT.keys;
% % disp(numel(keys))
% values = FT.values;
% for i = 1:numel(keys)
%     disp(['Father: ' keys{i} 'Son: ' values{i}]);
% end


%寻找线路
%EdgeNo与线路编号的映射
Line_num=containers.Map('KeyType','double','ValueType','any');
% 线路编号与EdgeNo的反向映射(方便include输出)
Num_line=containers.Map('KeyType','double','ValueType','any');
%初始化
origin_lineid=0;
fid=754;
root=fid;%需要搜索的元素
temp=[];%搜过和正在搜的元素
circul=[];%放合环线路的元素
sign=0;
lineid=0;
while ~isempty(root)
    current=root(1);%取出元素
    temp(end+1)=root(1);
    root(1)=[];%第一个元素删去
    if FT.isKey(current)
        children = FT(current);  %获取当前节点的子节点列表 
        children=cell2mat(children);
        for i = 1:numel(children)
            child = children(i);     
            %不要重复
            for k=1:numel(temp)
                if(child==temp(k))
                    sign=1; 
                end                
            end
            %合环线路节点
            c_child=cell2mat(FT(child));
            for k=1:numel(root)
                if child==root(k)&&numel(c_child)<=2
                    sign=2;
                    circul(end+1)=child;
                end
            end
            %如果满足要求，则为需要
            if sign==0||sign==2
                root(end+1) = child;                
                %寻找本支路和上段支路对应的EdgeNo编号                   
                for n=1:numel(origin_lines)
                    a=origin_lines(n).F_Node;
                    b=origin_lines(n).T_Node;
                    a2=table2array(a);
                    a3=table2array(b); 
                    if current==a2&&child==a3||current==a3&&child==a2                           
                        origin_lineid=origin_lines(n).EdgeNo; 
                        origin_lineid=table2array(origin_lineid);
                    end    
                    for m=1:numel(temp)
                        if (current==a2&&temp(m)==a3||current==a3&&temp(m)==a2)                            
                            near_lineid=origin_lines(n).EdgeNo;    
                            near_lineid=table2array(near_lineid);
                        end
                    end 
                end
                if numel(children)>=3||current==fid
                    lineid=lineid+1;
                    id=lineid;
                else                   
                    id=Line_num(near_lineid);     
                    id=cell2mat(id);
                end
                %构建映射关系
                if Line_num.isKey(origin_lineid)
                    Line_num(origin_lineid) = [Line_num(origin_lineid),{id}];
                else
                    Line_num(origin_lineid) = {id};
                end
                %id与EdgeNo反向映射（方便include输出）
                if Num_line.isKey(id)
                    Num_line(id) = [Num_line(id),{origin_lineid}];
                else
                    Num_line(id) = {origin_lineid};
                end
            end
            sign=0;                
        end
    end 
end

% keys = Num_line.keys;
% values = Num_line.values;
% for i = 1:numel(keys)
%     disp(['Father: ' keys{i} 'Son: ' values{i}]);
% end

%合环线路处理
c_line=[];
keys = Num_line.keys;
for i=1:numel(circul)
    for j=1:numel(keys)
        if Num_line.isKey(j)
            lineNo= cell2mat(Num_line(j));
            for k = 1:numel(lineNo)
                num=lineNo(k); 
                for m=1:numel(origin_lines)
                    line=table2array(origin_lines(m).EdgeNo); 
                    if num==line 
                        a=table2array(origin_lines(m).F_Node);
                        b=table2array(origin_lines(m).T_Node);  
                        if circul(i)==a||circul(i)==b
                            c_line(end+1)=line;
                        end
                    end
                end
            end
        end
    end
    idc1=cell2mat(Line_num(c_line(1)));
    idc2=cell2mat(Line_num(c_line(2)));
    if idc1~=idc2
        lineid=lineid+1;
        line1=cell2mat(Num_line(idc1));
        line2=cell2mat(Num_line(idc2));
        id=lineid;
        for j=1:numel(line1)
            if Num_line.isKey(id)
                Num_line(id) = [Num_line(id),{line1(j)}];
            else
                Num_line(id) = {line1(j)};
            end
        end
        for j=1:numel(line2)
            if Num_line.isKey(id)
                Num_line(id) = [Num_line(id),{line2(j)}];
            else
                Num_line(id) = {line2(j)};
            end
        end
    end
    Num_line.remove(idc1);
    Num_line.remove(idc2);
    idc1=0;
    idc2=0;
    c_line=[];
end

% keys = Num_line.keys;
% values = Num_line.values;
% for i = 1:numel(keys)
%     disp(['Father: ' keys{i} 'Son: ' values{i}]);
% end


%简化前后关系
resistance=0;
reactance=0;
susceptance=0;
is_active=1;
for i=1:lineid
    if Num_line.isKey(i)
        lineNo= Num_line(i);
        lineNo=cell2mat(lineNo);
        temp=[];
        tempm=[];
        bus=[];
        busm=[];
        resistance=0;
        reactance=0;
        susceptance=0;
        for j = 1:numel(lineNo)
            num=lineNo(j);        
            for n=1:numel(origin_lines)
                line=origin_lines(n).EdgeNo;        
                line=table2array(line);
                if num==line 
                    a=origin_lines(n).F_Node;
                    am=origin_lines(n).F_Node_map;
                    b=origin_lines(n).T_Node;
                    bm=origin_lines(n).T_Node_map;                
                    resistance=resistance+table2array(origin_lines(n).r);
                    reactance=reactance+table2array(origin_lines(n).x);
                    susceptance=susceptance+table2array(origin_lines(n).b);
                    temp(end+1)=table2array(a);
                    temp(end+1)=table2array(b);
                    tempm(end+1)=table2array(am);
                    tempm(end+1)=table2array(bm);
                    include(end+1)=struct('lines',i,'origin_lines',num,'F_Node',a,'T_Node',b);
                end            
            end                
        end
        %找化简后起始与结束节点        
        for m=1:numel(temp)
            sign=0;            
            for k=1:numel(temp)                
                if temp(m)==temp(k)&&k~=m
                    sign=1;
                end
            end
            if sign==0
                bus(end+1)=temp(m);
                busm(end+1)=tempm(m);
            end
        end
        lines(end+1)=struct('id',i,'from_bus',bus(1),'from_bus_map',busm(1),'to_bus',bus(2),'to_bus_map',busm(2),'resistance',resistance,'reactance',reactance,'susceptance',susceptance,'is_active',is_active);
    end
end

%化简后可以控制线路断开闭合的断路器
%找和节点相连的断路器
bus_Breaker=containers.Map('KeyType','double','ValueType','any');
allkeys=FT.keys();
for i=1:numel(allkeys)
    father=cell2mat(allkeys(i));
    sons=cell2mat(FT(father));
    if numel(sons)>=3
        for j=1:numel(sons)
            son=sons(j);
            for n=1:numel(origin_lines)
                a=table2array(origin_lines(n).F_Node);
                b=table2array(origin_lines(n).T_Node);
                type=table2array(origin_lines(n).type);
                if (father==a&&son==b||father==b&&son==a)&&strcmp(type,'断路器')
                    typeid=cell2mat(table2array(origin_lines(n).typeid));
                    if bus_Breaker.isKey(father)
                        bus_Breaker(father) = [bus_Breaker(father),{typeid}];
                    else
                        bus_Breaker(father) = {typeid};
                    end
                end  
            end
        end
    end
end

% keys = bus_Breaker.keys;
% values = bus_Breaker.values;
% for i = 1:numel(keys)
%     disp(['Father: ' keys{i} 'Son: ' values{i}]);
% end

% 化简后线路与断路器映射关系
line_Breaker=containers.Map('KeyType','double','ValueType','any');
for i=1:lineid
    if Num_line.isKey(i)
        lineNo= cell2mat(Num_line(i));     
        for j = 1:numel(lineNo)
            num=lineNo(j);        
            for n=1:numel(origin_lines)
                line=table2array(origin_lines(n).EdgeNo);  
                if num==line 
                    type=table2array(origin_lines(n).type);
                    a=table2array(origin_lines(n).F_Node);
                    b=table2array(origin_lines(n).T_Node);
                    if strcmp(type,'断路器')
                        typeid=cell2mat(table2array(origin_lines(n).typeid));
                        if line_Breaker.isKey(i)
                            line_Breaker(i) = [line_Breaker(i),{typeid}];
                        else
                            line_Breaker(i) = {typeid};
                        end
                    elseif strcmp(type,'刀闸')
                        for m=1:numel(lines)
                            fa=lines(m).from_bus;
                            tb=lines(m).to_bus;
                            if (fa==a||fa==b)&&bus_Breaker.isKey(fa)
                                typeid=string(bus_Breaker(fa));
                                abcde=string(bus_Breaker(fa));
                                sign=1;
                            elseif (tb==a||tb==b)&&bus_Breaker.isKey(tb)
                                typeid=string(bus_Breaker(tb));
                                abcde=string(bus_Breaker(tb));
                                sign=1;
                            end 
                        end 
                        if sign==1
                            if line_Breaker.isKey(i)
                                line_Breaker(i) = [line_Breaker(i),{typeid}];
                            else
                                line_Breaker(i) = {typeid};
                            end
                            disp(i)
                        end
                    end
                    sign=0;
                end            
            end                
        end
    end
end

keys = line_Breaker.keys;
values = line_Breaker.values;
for i = 1:numel(keys)
    disp([ keys{i}   values{i}]);
end

line_breaker_struct=struct('id',{},'breaker',{});
breakerid=[];
for i=1:lineid
    if line_Breaker.isKey(i)
        breakername= line_Breaker(i);     
        for j = 1:numel(breakername)  
            if cellfun(@isstring, breakername(j))
                breaker=convertStringsToChars(breakername(j));
                for k = 1:length(breaker{1})
                    breakerid = breaker{1}(k);
                    line_breaker_struct(end+1)=struct('id',i,'breaker',breakerid);
                end
            else
                breaker=cell2mat(breakername(j));
                line_breaker_struct(end+1)=struct('id',i,'breaker',breaker);
            end
        end
    end
    breakerid=[];
end

disp(struct2table(lines));
disp(struct2table(include));
disp(struct2table(line_breaker_struct))

% 将结构体转换为表格
lines_table = struct2table(lines);
include_table = struct2table(include);
breaker_table = struct2table(line_breaker_struct);

% 拆分嵌套变量
lines_table = splitvars(lines_table);
include_table = splitvars(include_table);
breaker_table = splitvars(breaker_table);

% 写入Excel文件
writetable(lines_table, linenamexlsx);
writetable(include_table, includenamexlsx);
writetable(breaker_table, breakernamexlsx);


